/*
 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef UpdateFields_h__
#define UpdateFields_h__

#include "EnumFlag.h"
#include "ItemPacketsCommon.h"
#include "MythicPlusPacketsCommon.h"
#include "ObjectGuid.h"
#include "PerksProgramPacketsCommon.h"
#include "Position.h"
#include "QuaternionData.h"
#include "UpdateField.h"
#include "UpdateMask.h"

// This file is automatically generated, DO NOT EDIT

class AreaTrigger;
class AzeriteEmpoweredItem;
class AzeriteItem;
class Bag;
class ByteBuffer;
class Conversation;
class Corpse;
class DynamicObject;
class GameObject;
class Item;
class Object;
class Player;
class Unit;

namespace UF
{
struct ObjectData : public IsUpdateFieldStructureTag, public HasChangesMask<4>
{
    UpdateField<int32, 0, 1> EntryID;
    struct EntryIDTag : ViewerDependentValueTag<int32> {};
    UpdateField<uint32, 0, 2> DynamicFlags;
    struct DynamicFlagsTag : ViewerDependentValueTag<uint32> {};
    UpdateField<float, 0, 3> Scale;

    void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Object const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct ItemEnchantment : public IsUpdateFieldStructureTag, public HasChangesMask<5>
{
    UpdateField<int32, 0, 1> ID;
    UpdateField<uint32, 0, 2> Duration;
    UpdateField<int16, 0, 3> Charges;
    UpdateField<uint16, 0, 4> Inactive;

    void WriteCreate(ByteBuffer& data, Item const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Item const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct ItemMod : public IsUpdateFieldStructureTag
{
    int32 Value;
    uint8 Type;

    void WriteCreate(ByteBuffer& data, Item const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Item const* owner, Player const* receiver) const;
    bool operator==(ItemMod const& right) const;
    bool operator!=(ItemMod const& right) const { return !(*this == right); }
};

struct ItemModList : public IsUpdateFieldStructureTag, public HasChangesMask<1>
{
    DynamicUpdateField<UF::ItemMod, -1, 0> Values;

    void WriteCreate(ByteBuffer& data, Item const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Item const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct ArtifactPower : public IsUpdateFieldStructureTag
{
    int16 ArtifactPowerID;
    uint8 PurchasedRank;
    uint8 CurrentRankWithBonus;

    void WriteCreate(ByteBuffer& data, Item const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Item const* owner, Player const* receiver) const;
    bool operator==(ArtifactPower const& right) const;
    bool operator!=(ArtifactPower const& right) const { return !(*this == right); }
};

struct SocketedGem : public IsUpdateFieldStructureTag, public HasChangesMask<20>
{
    UpdateField<int32, 0, 1> ItemID;
    UpdateField<uint8, 0, 2> Context;
    UpdateFieldArray<uint16, 16, 3, 4> BonusListIDs;

    void WriteCreate(ByteBuffer& data, Item const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Item const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct ItemData : public IsUpdateFieldStructureTag, public HasChangesMask<41>
{
    DynamicUpdateField<UF::ArtifactPower, 0, 1> ArtifactPowers;
    DynamicUpdateField<UF::SocketedGem, 0, 2> Gems;
    UpdateField<ObjectGuid, 0, 3> Owner;
    UpdateField<ObjectGuid, 0, 4> ContainedIn;
    UpdateField<ObjectGuid, 0, 5> Creator;
    UpdateField<ObjectGuid, 0, 6> GiftCreator;
    UpdateField<uint32, 0, 7> StackCount;
    UpdateField<uint32, 0, 8> Expiration;
    UpdateField<uint32, 0, 9> DynamicFlags;
    UpdateField<uint32, 0, 10> Durability;
    UpdateField<uint32, 0, 11> MaxDurability;
    UpdateField<uint32, 0, 12> CreatePlayedTime;
    UpdateField<int32, 0, 13> Context;
    UpdateField<int64, 0, 14> CreateTime;
    UpdateField<uint64, 0, 15> ArtifactXP;
    UpdateField<uint8, 0, 16> ItemAppearanceModID;
    UpdateField<UF::ItemModList, 0, 17> Modifiers;
    UpdateField<uint32, 0, 18> DynamicFlags2;
    UpdateField<WorldPackets::Item::ItemBonusKey, 0, 19> ItemBonusKey;
    UpdateField<uint16, 0, 20> DEBUGItemLevel;
    UpdateFieldArray<int32, 5, 21, 22> SpellCharges;
    UpdateFieldArray<UF::ItemEnchantment, 13, 27, 28> Enchantment;

    void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Item const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Item const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Item const* owner, Player const* receiver) const;
    static void AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags);
    static void FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags);
    void ClearChangesMask();
};

struct ContainerData : public IsUpdateFieldStructureTag, public HasChangesMask<39>
{
    UpdateField<uint32, 0, 1> NumSlots;
    UpdateFieldArray<ObjectGuid, 36, 2, 3> Slots;

    void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Bag const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Bag const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Bag const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct AzeriteEmpoweredItemData : public IsUpdateFieldStructureTag, public HasChangesMask<6>
{
    UpdateFieldArray<int32, 5, 0, 1> Selections;

    void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, AzeriteEmpoweredItem const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, AzeriteEmpoweredItem const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, AzeriteEmpoweredItem const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct UnlockedAzeriteEssence : public IsUpdateFieldStructureTag
{
    uint32 AzeriteEssenceID;
    uint32 Rank;

    void WriteCreate(ByteBuffer& data, AzeriteItem const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AzeriteItem const* owner, Player const* receiver) const;
    bool operator==(UnlockedAzeriteEssence const& right) const;
    bool operator!=(UnlockedAzeriteEssence const& right) const { return !(*this == right); }
};

struct SelectedAzeriteEssences : public IsUpdateFieldStructureTag, public HasChangesMask<8>
{
    UpdateField<bool, 0, 1> Enabled;
    UpdateField<uint32, 0, 2> SpecializationID;
    UpdateFieldArray<uint32, 4, 3, 4> AzeriteEssenceID;

    void WriteCreate(ByteBuffer& data, AzeriteItem const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AzeriteItem const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct AzeriteItemData : public IsUpdateFieldStructureTag, public HasChangesMask<10>
{
    UpdateField<bool, 0, 1> Enabled;
    DynamicUpdateField<UF::UnlockedAzeriteEssence, 0, 2> UnlockedEssences;
    DynamicUpdateField<uint32, 0, 4> UnlockedEssenceMilestones;
    DynamicUpdateField<UF::SelectedAzeriteEssences, 0, 3> SelectedEssences;
    UpdateField<uint64, 0, 5> Xp;
    UpdateField<uint32, 0, 6> Level;
    UpdateField<uint32, 0, 7> AuraLevel;
    UpdateField<uint32, 0, 8> KnowledgeLevel;
    UpdateField<int32, 0, 9> DEBUGknowledgeWeek;

    void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, AzeriteItem const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, AzeriteItem const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, AzeriteItem const* owner, Player const* receiver) const;
    static void AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags);
    static void FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags);
    void ClearChangesMask();
};

struct SpellCastVisual : public IsUpdateFieldStructureTag
{
    int32 SpellXSpellVisualID;
    int32 ScriptVisualID;

    void WriteCreate(ByteBuffer& data, Object const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Object const* owner, Player const* receiver) const;
    bool operator==(SpellCastVisual const& right) const;
    bool operator!=(SpellCastVisual const& right) const { return !(*this == right); }
};

struct UnitChannel : public IsUpdateFieldStructureTag
{
    int32 SpellID;
    UF::SpellCastVisual SpellVisual;

    void WriteCreate(ByteBuffer& data, Unit const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Unit const* owner, Player const* receiver) const;
    bool operator==(UnitChannel const& right) const;
    bool operator!=(UnitChannel const& right) const { return !(*this == right); }
};

struct VisibleItem : public IsUpdateFieldStructureTag, public HasChangesMask<6>
{
    UpdateField<int32, 0, 1> ItemID;
    UpdateField<int32, 0, 2> SecondaryItemModifiedAppearanceID;
    UpdateField<int32, 0, 3> ConditionalItemAppearanceID;
    UpdateField<uint16, 0, 4> ItemAppearanceModID;
    UpdateField<uint16, 0, 5> ItemVisual;

    void WriteCreate(ByteBuffer& data, Unit const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Unit const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct PassiveSpellHistory : public IsUpdateFieldStructureTag
{
    int32 SpellID;
    int32 AuraSpellID;

    void WriteCreate(ByteBuffer& data, Unit const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Unit const* owner, Player const* receiver) const;
    bool operator==(PassiveSpellHistory const& right) const;
    bool operator!=(PassiveSpellHistory const& right) const { return !(*this == right); }
};

struct UnitData : public IsUpdateFieldStructureTag, public HasChangesMask<217>
{
    UpdateField<std::vector<uint32>, 0, 1> StateWorldEffectIDs;
    struct StateWorldEffectIDsTag : ViewerDependentValueTag<std::vector<uint32>> {};
    DynamicUpdateField<UF::PassiveSpellHistory, 0, 2> PassiveSpells;
    DynamicUpdateField<int32, 0, 3> WorldEffects;
    DynamicUpdateField<ObjectGuid, 0, 4> ChannelObjects;
    UpdateField<int32, 0, 5> DisplayID;
    struct DisplayIDTag : ViewerDependentValueTag<int32> {};
    UpdateField<uint32, 0, 6> StateSpellVisualID;
    struct StateSpellVisualIDTag : ViewerDependentValueTag<uint32> {};
    UpdateField<uint32, 0, 7> StateAnimID;
    struct StateAnimIDTag : ViewerDependentValueTag<uint32> {};
    UpdateField<uint32, 0, 8> StateAnimKitID;
    struct StateAnimKitIDTag : ViewerDependentValueTag<uint32> {};
    UpdateField<uint32, 0, 9> StateWorldEffectsQuestObjectiveID;
    UpdateField<int32, 0, 10> SpellOverrideNameID;
    UpdateField<ObjectGuid, 0, 11> Charm;
    UpdateField<ObjectGuid, 0, 12> Summon;
    UpdateField<ObjectGuid, 0, 13> Critter;
    UpdateField<ObjectGuid, 0, 14> CharmedBy;
    UpdateField<ObjectGuid, 0, 15> SummonedBy;
    UpdateField<ObjectGuid, 0, 16> CreatedBy;
    UpdateField<ObjectGuid, 0, 17> DemonCreator;
    UpdateField<ObjectGuid, 0, 18> LookAtControllerTarget;
    UpdateField<ObjectGuid, 0, 19> Target;
    UpdateField<ObjectGuid, 0, 20> BattlePetCompanionGUID;
    UpdateField<uint64, 0, 21> BattlePetDBID;
    UpdateField<UF::UnitChannel, 0, 22> ChannelData;
    UpdateField<int8, 0, 23> SpellEmpowerStage;
    UpdateField<uint32, 0, 24> SummonedByHomeRealm;
    UpdateField<uint8, 0, 25> Race;
    UpdateField<uint8, 0, 26> ClassId;
    UpdateField<uint8, 0, 27> PlayerClassId;
    UpdateField<uint8, 0, 28> Sex;
    UpdateField<uint8, 0, 29> DisplayPower;
    UpdateField<uint32, 0, 30> OverrideDisplayPowerID;
    UpdateField<int64, 0, 31> Health;
    UpdateField<int64, 32, 33> MaxHealth;
    UpdateField<int32, 32, 34> Level;
    UpdateField<int32, 32, 35> EffectiveLevel;
    UpdateField<int32, 32, 36> ContentTuningID;
    UpdateField<int32, 32, 37> ScalingLevelMin;
    UpdateField<int32, 32, 38> ScalingLevelMax;
    UpdateField<int32, 32, 39> ScalingLevelDelta;
    UpdateField<int32, 32, 40> ScalingFactionGroup;
    UpdateField<int32, 32, 41> FactionTemplate;
    struct FactionTemplateTag : ViewerDependentValueTag<int32> {};
    UpdateField<uint32, 32, 42> Flags;
    struct FlagsTag : ViewerDependentValueTag<uint32> {};
    UpdateField<uint32, 32, 43> Flags2;
    struct Flags2Tag : ViewerDependentValueTag<uint32> {};
    UpdateField<uint32, 32, 44> Flags3;
    struct Flags3Tag : ViewerDependentValueTag<uint32> {};
    UpdateField<uint32, 32, 45> AuraState;
    struct AuraStateTag : ViewerDependentValueTag<uint32> {};
    UpdateField<uint32, 32, 46> RangedAttackRoundBaseTime;
    UpdateField<float, 32, 47> BoundingRadius;
    UpdateField<float, 32, 48> CombatReach;
    UpdateField<float, 32, 49> DisplayScale;
    UpdateField<int32, 32, 50> CreatureFamily;
    UpdateField<int32, 32, 51> CreatureType;
    UpdateField<int32, 32, 52> NativeDisplayID;
    UpdateField<float, 32, 53> NativeXDisplayScale;
    UpdateField<int32, 32, 54> MountDisplayID;
    UpdateField<int32, 32, 55> CosmeticMountDisplayID;
    UpdateField<float, 32, 56> MinDamage;
    UpdateField<float, 32, 57> MaxDamage;
    UpdateField<float, 32, 58> MinOffHandDamage;
    UpdateField<float, 32, 59> MaxOffHandDamage;
    UpdateField<uint8, 32, 60> StandState;
    UpdateField<uint8, 32, 61> PetTalentPoints;
    UpdateField<uint8, 32, 62> VisFlags;
    UpdateField<uint8, 32, 63> AnimTier;
    UpdateField<uint32, 64, 65> PetNumber;
    UpdateField<uint32, 64, 66> PetNameTimestamp;
    UpdateField<uint32, 64, 67> PetExperience;
    UpdateField<uint32, 64, 68> PetNextLevelExperience;
    UpdateField<float, 64, 69> ModCastingSpeed;
    UpdateField<float, 64, 70> ModCastingSpeedNeg;
    UpdateField<float, 64, 71> ModSpellHaste;
    UpdateField<float, 64, 72> ModHaste;
    UpdateField<float, 64, 73> ModRangedHaste;
    UpdateField<float, 64, 74> ModHasteRegen;
    UpdateField<float, 64, 75> ModTimeRate;
    UpdateField<int32, 64, 76> CreatedBySpell;
    UpdateField<int32, 64, 77> EmoteState;
    UpdateField<int32, 64, 78> BaseMana;
    UpdateField<int32, 64, 79> BaseHealth;
    UpdateField<uint8, 64, 80> SheatheState;
    UpdateField<uint8, 64, 81> PvpFlags;
    struct PvpFlagsTag : ViewerDependentValueTag<uint8> {};
    UpdateField<uint8, 64, 82> PetFlags;
    UpdateField<uint8, 64, 83> ShapeshiftForm;
    UpdateField<int32, 64, 84> AttackPower;
    UpdateField<int32, 64, 85> AttackPowerModPos;
    UpdateField<int32, 64, 86> AttackPowerModNeg;
    UpdateField<float, 64, 87> AttackPowerMultiplier;
    UpdateField<int32, 64, 88> AttackPowerModSupport;
    UpdateField<int32, 64, 89> RangedAttackPower;
    UpdateField<int32, 64, 90> RangedAttackPowerModPos;
    UpdateField<int32, 64, 91> RangedAttackPowerModNeg;
    UpdateField<float, 64, 92> RangedAttackPowerMultiplier;
    UpdateField<int32, 64, 93> RangedAttackPowerModSupport;
    UpdateField<int32, 64, 94> MainHandWeaponAttackPower;
    UpdateField<int32, 64, 95> OffHandWeaponAttackPower;
    UpdateField<int32, 96, 97> RangedWeaponAttackPower;
    UpdateField<int32, 96, 98> SetAttackSpeedAura;
    UpdateField<float, 96, 99> Lifesteal;
    UpdateField<float, 96, 100> MinRangedDamage;
    UpdateField<float, 96, 101> MaxRangedDamage;
    UpdateField<float, 96, 102> ManaCostMultiplier;
    UpdateField<float, 96, 103> MaxHealthModifier;
    UpdateField<float, 96, 104> HoverHeight;
    UpdateField<int32, 96, 105> MinItemLevelCutoff;
    UpdateField<int32, 96, 106> MinItemLevel;
    UpdateField<int32, 96, 107> MaxItemLevel;
    UpdateField<int32, 96, 108> AzeriteItemLevel;
    UpdateField<int32, 96, 109> WildBattlePetLevel;
    UpdateField<int32, 96, 110> BattlePetCompanionExperience;
    UpdateField<uint32, 96, 111> BattlePetCompanionNameTimestamp;
    UpdateField<int32, 96, 112> InteractSpellID;
    struct InteractSpellIDTag : ViewerDependentValueTag<int32> {};
    UpdateField<int32, 96, 113> ScaleDuration;
    UpdateField<int32, 96, 114> LooksLikeMountID;
    UpdateField<int32, 96, 115> LooksLikeCreatureID;
    UpdateField<int32, 96, 116> LookAtControllerID;
    UpdateField<int32, 96, 117> PerksVendorItemID;
    UpdateField<int32, 96, 118> TaxiNodesID;
    UpdateField<ObjectGuid, 96, 119> GuildGUID;
    UpdateField<int32, 96, 120> FlightCapabilityID;
    UpdateField<float, 96, 121> GlideEventSpeedDivisor;                         // Movement speed gets divided by this value when evaluating what GlideEvents to use
    UpdateField<uint32, 96, 122> Field_308;
    UpdateField<uint32, 96, 123> Field_30C;
    UpdateField<uint32, 96, 124> SilencedSchoolMask;
    UpdateField<uint32, 96, 125> CurrentAreaID;
    UpdateField<ObjectGuid, 96, 126> NameplateAttachToGUID;                     // When set, nameplate of this unit will instead appear on that object
    UpdateFieldArray<uint32, 2, 127, 128> NpcFlags;
    struct NpcFlagsTag : ViewerDependentValueTag<uint32> {};
    UpdateFieldArray<int32, 10, 130, 131> Power;
    UpdateFieldArray<int32, 10, 130, 141> MaxPower;
    UpdateFieldArray<float, 10, 130, 151> PowerRegenFlatModifier;
    UpdateFieldArray<float, 10, 130, 161> PowerRegenInterruptedFlatModifier;
    UpdateFieldArray<UF::VisibleItem, 3, 171, 172> VirtualItems;
    UpdateFieldArray<uint32, 2, 175, 176> AttackRoundBaseTime;
    UpdateFieldArray<int32, 4, 178, 179> Stats;
    UpdateFieldArray<int32, 4, 178, 183> StatPosBuff;
    UpdateFieldArray<int32, 4, 178, 187> StatNegBuff;
    UpdateFieldArray<int32, 4, 178, 191> StatSupportBuff;
    UpdateFieldArray<int32, 7, 195, 196> Resistances;
    UpdateFieldArray<int32, 7, 195, 203> BonusResistanceMods;
    UpdateFieldArray<int32, 7, 195, 210> ManaCostModifier;

    void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Unit const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Unit const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Unit const* owner, Player const* receiver) const;
    static void AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags);
    static void FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags);
    void ClearChangesMask();
};

struct ChrCustomizationChoice : public IsUpdateFieldStructureTag
{
    uint32 ChrCustomizationOptionID;
    uint32 ChrCustomizationChoiceID;

    void WriteCreate(ByteBuffer& data, Object const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Object const* owner, Player const* receiver) const;
    bool operator==(ChrCustomizationChoice const& right) const;
    bool operator!=(ChrCustomizationChoice const& right) const { return !(*this == right); }
};

struct QuestLog : public IsUpdateFieldStructureTag, public HasChangesMask<30>
{
    UpdateField<int64, 0, 1> EndTime;
    UpdateField<int32, 0, 2> QuestID;
    UpdateField<uint32, 0, 3> StateFlags;
    UpdateField<uint32, 0, 4> ObjectiveFlags;
    UpdateFieldArray<int16, 24, 5, 6> ObjectiveProgress;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct ArenaCooldown : public IsUpdateFieldStructureTag, public HasChangesMask<8>
{
    UpdateField<int32, 0, 1> SpellID;
    UpdateField<int32, 0, 2> Charges;
    UpdateField<uint32, 0, 3> Flags;
    UpdateField<uint32, 0, 4> StartTime;
    UpdateField<uint32, 0, 5> EndTime;
    UpdateField<uint32, 0, 6> NextChargeTime;
    UpdateField<uint8, 0, 7> MaxCharges;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct PetCreatureName : public IsUpdateFieldStructureTag, public HasChangesMask<3>
{
    UpdateField<uint32, 0, 1> CreatureID;
    UpdateField<std::string, 0, 2> Name;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct CTROptions : public IsUpdateFieldStructureTag
{
    int32 ContentTuningConditionMask;
    uint32 Field_4;
    uint32 ExpansionLevelMask;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    bool operator==(CTROptions const& right) const;
    bool operator!=(CTROptions const& right) const { return !(*this == right); }
};

struct DeclinedNames : public IsUpdateFieldStructureTag, public HasChangesMask<6>
{
    UpdateFieldArray<std::string, 5, 0, 1> Name;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct CustomTabardInfo : public IsUpdateFieldStructureTag, public HasChangesMask<6>
{
    UpdateField<int32, 0, 1> EmblemStyle;
    UpdateField<int32, 0, 2> EmblemColor;
    UpdateField<int32, 0, 3> BorderStyle;
    UpdateField<int32, 0, 4> BorderColor;
    UpdateField<int32, 0, 5> BackgroundColor;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct PlayerData : public IsUpdateFieldStructureTag, public HasChangesMask<289>
{
    UpdateField<bool, 0, 1> HasQuestSession;
    UpdateField<bool, 0, 2> HasLevelLink;
    DynamicUpdateField<UF::ChrCustomizationChoice, 0, 3> Customizations;
    DynamicUpdateField<UF::ChrCustomizationChoice, 0, 4> QaCustomizations;
    DynamicUpdateField<UF::QuestLog, 0, 5> QuestSessionQuestLog;
    DynamicUpdateField<UF::ArenaCooldown, 0, 6> ArenaCooldowns;
    DynamicUpdateField<int32, 0, 8> VisualItemReplacements;
    DynamicUpdateField<UF::PetCreatureName, 0, 7> PetNames;
    UpdateField<ObjectGuid, 0, 9> DuelArbiter;
    UpdateField<ObjectGuid, 0, 10> WowAccount;
    UpdateField<ObjectGuid, 0, 11> BnetAccount;
    UpdateField<uint64, 0, 12> GuildClubMemberID;
    UpdateField<ObjectGuid, 0, 13> LootTargetGUID;
    UpdateField<uint32, 0, 14> PlayerFlags;
    UpdateField<uint32, 0, 15> PlayerFlagsEx;
    UpdateField<uint32, 0, 16> GuildRankID;
    UpdateField<uint32, 0, 17> GuildDeleteDate;
    UpdateField<int32, 0, 18> GuildLevel;
    UpdateField<uint8, 0, 19> NativeSex;
    UpdateField<uint8, 0, 20> Inebriation;
    UpdateField<uint8, 0, 21> PvpTitle;
    UpdateField<uint8, 0, 22> ArenaFaction;
    UpdateField<uint32, 0, 23> DuelTeam;
    UpdateField<int32, 0, 24> GuildTimeStamp;
    UpdateField<int32, 0, 25> PlayerTitle;
    UpdateField<int32, 0, 26> FakeInebriation;
    UpdateField<uint32, 0, 27> VirtualPlayerRealm;
    UpdateField<uint32, 0, 28> CurrentSpecID;
    UpdateField<int32, 0, 29> TaxiMountAnimKitID;
    UpdateField<uint8, 0, 30> CurrentBattlePetBreedQuality;
    UpdateField<int32, 0, 31> HonorLevel;
    UpdateField<int64, 32, 33> LogoutTime;
    UpdateField<std::string, 32, 34> Name;
    UpdateField<int32, 32, 35> Field_1AC;
    UpdateField<int32, 32, 36> Field_1B0;
    UpdateField<int32, 32, 37> CurrentBattlePetSpeciesID;
    UpdateField<UF::CTROptions, 32, 38> CtrOptions;
    UpdateField<int32, 32, 39> CovenantID;
    UpdateField<int32, 32, 40> SoulbindID;
    UpdateField<WorldPackets::MythicPlus::DungeonScoreSummary, 32, 41> DungeonScore;
    UpdateField<ObjectGuid, 32, 42> SpectateTarget;
    UpdateField<int32, 32, 43> Field_200;
    OptionalUpdateField<UF::DeclinedNames, 32, 44> DeclinedNames;
    UpdateField<UF::CustomTabardInfo, 32, 45> PersonalTabard;
    UpdateFieldArray<uint8, 2, 46, 47> PartyType;
    UpdateFieldArray<UF::QuestLog, 175, 49, 50> QuestLog;
    UpdateFieldArray<UF::VisibleItem, 19, 225, 226> VisibleItems;
    UpdateFieldArray<float, 6, 245, 246> AvgItemLevel;
    UpdateFieldArray<WorldPackets::Item::ItemInstance, 16, 252, 253> VisibleEquipableSpells;
    UpdateFieldArray<uint32, 19, 269, 270> Field_3120;

    void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Player const* owner, Player const* receiver) const;
    static void AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags);
    static void FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags);
    void ClearChangesMask();
    bool IsQuestLogChangesMaskSkipped() const { return false; } // bandwidth savings aren't worth the cpu time
};

struct SkillInfo : public IsUpdateFieldStructureTag, public HasChangesMask<1793>
{
    UpdateFieldArray<uint16, 256, 0, 1> SkillLineID;
    UpdateFieldArray<uint16, 256, 0, 257> SkillStep;
    UpdateFieldArray<uint16, 256, 0, 513> SkillRank;
    UpdateFieldArray<uint16, 256, 0, 769> SkillStartingRank;
    UpdateFieldArray<uint16, 256, 0, 1025> SkillMaxRank;
    UpdateFieldArray<int16, 256, 0, 1281> SkillTempBonus;
    UpdateFieldArray<uint16, 256, 0, 1537> SkillPermBonus;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct RestInfo : public IsUpdateFieldStructureTag, public HasChangesMask<3>
{
    UpdateField<uint32, 0, 1> Threshold;
    UpdateField<uint8, 0, 2> StateID;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct PVPInfo : public IsUpdateFieldStructureTag, public HasChangesMask<19>
{
    UpdateField<bool, 0, 1> Disqualified;
    UpdateField<int8, 0, 2> Bracket;
    UpdateField<int32, 0, 3> PvpRatingID;
    UpdateField<uint32, 0, 4> WeeklyPlayed;
    UpdateField<uint32, 0, 5> WeeklyWon;
    UpdateField<uint32, 0, 6> SeasonPlayed;
    UpdateField<uint32, 0, 7> SeasonWon;
    UpdateField<uint32, 0, 8> Rating;
    UpdateField<uint32, 0, 9> WeeklyBestRating;
    UpdateField<uint32, 0, 10> SeasonBestRating;
    UpdateField<uint32, 0, 11> PvpTierID;
    UpdateField<uint32, 0, 12> WeeklyBestWinPvpTierID;
    UpdateField<uint32, 0, 13> Field_28;
    UpdateField<uint32, 0, 14> Field_2C;
    UpdateField<uint32, 0, 15> WeeklyRoundsPlayed;
    UpdateField<uint32, 0, 16> WeeklyRoundsWon;
    UpdateField<uint32, 0, 17> SeasonRoundsPlayed;
    UpdateField<uint32, 0, 18> SeasonRoundsWon;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct CharacterRestriction : public IsUpdateFieldStructureTag
{
    int32 Field_0;
    int32 Field_4;
    int32 Field_8;
    uint32 Type;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    bool operator==(CharacterRestriction const& right) const;
    bool operator!=(CharacterRestriction const& right) const { return !(*this == right); }
};

struct SpellPctModByLabel : public IsUpdateFieldStructureTag
{
    int32 ModIndex;
    float ModifierValue;
    int32 LabelID;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    bool operator==(SpellPctModByLabel const& right) const;
    bool operator!=(SpellPctModByLabel const& right) const { return !(*this == right); }
};

struct SpellFlatModByLabel : public IsUpdateFieldStructureTag
{
    int32 ModIndex;
    int32 ModifierValue;
    int32 LabelID;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    bool operator==(SpellFlatModByLabel const& right) const;
    bool operator!=(SpellFlatModByLabel const& right) const { return !(*this == right); }
};

struct CompletedProject : public IsUpdateFieldStructureTag, public HasChangesMask<4>
{
    UpdateField<uint32, 0, 1> ProjectID;
    UpdateField<int64, 0, 2> FirstCompleted;
    UpdateField<uint32, 0, 3> CompletionCount;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct ResearchHistory : public IsUpdateFieldStructureTag, public HasChangesMask<2>
{
    DynamicUpdateField<UF::CompletedProject, 0, 1> CompletedProjects;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct MawPower : public IsUpdateFieldStructureTag
{
    int32 SpellID;
    int32 MawPowerID;
    int32 Stacks;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    bool operator==(MawPower const& right) const;
    bool operator!=(MawPower const& right) const { return !(*this == right); }
};

struct MultiFloorExplore : public IsUpdateFieldStructureTag
{
    std::vector<int32> WorldMapOverlayIDs;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    bool operator==(MultiFloorExplore const& right) const;
    bool operator!=(MultiFloorExplore const& right) const { return !(*this == right); }
};

struct RecipeProgressionInfo : public IsUpdateFieldStructureTag
{
    uint16 RecipeProgressionGroupID;
    uint16 Experience;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    bool operator==(RecipeProgressionInfo const& right) const;
    bool operator!=(RecipeProgressionInfo const& right) const { return !(*this == right); }
};

struct ActivePlayerUnk901 : public IsUpdateFieldStructureTag, public HasChangesMask<3>
{
    UpdateField<ObjectGuid, 0, 1> Field_0;
    UpdateField<int32, 0, 2> Field_10;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct QuestSession : public IsUpdateFieldStructureTag, public HasChangesMask<953>
{
    UpdateField<ObjectGuid, 0, 1> Owner;
    UpdateFieldArray<uint64, 950, 2, 3> QuestCompleted;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct ReplayedQuest : public IsUpdateFieldStructureTag, public HasChangesMask<3>
{
    UpdateField<int32, 0, 1> QuestID;
    UpdateField<uint32, 0, 2> ReplayTime;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct TraitEntry : public IsUpdateFieldStructureTag
{
    int32 TraitNodeID;
    int32 TraitNodeEntryID;
    int32 Rank;
    int32 GrantedRanks;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    bool operator==(TraitEntry const& right) const;
    bool operator!=(TraitEntry const& right) const { return !(*this == right); }
};

struct TraitConfig : public IsUpdateFieldStructureTag, public HasChangesMask<12>
{
    DynamicUpdateField<UF::TraitEntry, 0, 1> Entries;
    UpdateField<int32, 0, 2> ID;
    UpdateField<std::string, 0, 3> Name;
    UpdateField<int32, 4, 5> Type;
    UpdateField<int32, 4, 6> SkillLineID;
    UpdateField<int32, 4, 7> ChrSpecializationID;
    UpdateField<int32, 8, 9> CombatConfigFlags;
    UpdateField<int32, 8, 10> LocalIdentifier;
    UpdateField<int32, 8, 11> TraitSystemID;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct CraftingOrderItem : public IsUpdateFieldStructureTag, public HasChangesMask<7>
{
    UpdateField<uint64, -1, 0> Field_0;
    UpdateField<ObjectGuid, -1, 1> ItemGUID;
    UpdateField<ObjectGuid, -1, 2> OwnerGUID;
    UpdateField<int32, -1, 3> ItemID;
    UpdateField<uint32, -1, 4> Quantity;
    UpdateField<int32, -1, 5> ReagentQuality;
    OptionalUpdateField<uint8, -1, 6> DataSlotIndex;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct CraftingOrderData : public IsUpdateFieldStructureTag, public HasChangesMask<24>
{
    DynamicUpdateField<UF::CraftingOrderItem, 0, 1> Reagents;
    UpdateField<int32, 0, 2> Field_0;
    UpdateField<uint64, 0, 3> OrderID;
    UpdateField<int32, 0, 4> SkillLineAbilityID;
    UpdateField<uint8, 5, 6> OrderState;
    UpdateField<uint8, 5, 7> OrderType;
    UpdateField<uint8, 5, 8> MinQuality;
    UpdateField<int64, 5, 9> ExpirationTime;
    UpdateField<int64, 10, 11> ClaimEndTime;
    UpdateField<int64, 10, 12> TipAmount;
    UpdateField<int64, 10, 13> ConsortiumCut;
    UpdateField<uint32, 10, 14> Flags;
    UpdateField<ObjectGuid, 15, 16> CustomerGUID;
    UpdateField<ObjectGuid, 15, 17> CustomerAccountGUID;
    UpdateField<ObjectGuid, 15, 18> CrafterGUID;
    UpdateField<ObjectGuid, 15, 19> PersonalCrafterGUID;
    UpdateField<std::string, 20, 21> CustomerNotes;
    OptionalUpdateField<UF::CraftingOrderItem, 20, 22> OutputItem;
    OptionalUpdateField<WorldPackets::Item::ItemInstance, 20, 23> OutputItemData;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct CraftingOrder : public IsUpdateFieldStructureTag, public HasChangesMask<4>
{
    DynamicUpdateField<WorldPackets::Item::ItemEnchantData, -1, 0> Enchantments;
    DynamicUpdateField<WorldPackets::Item::ItemGemData, -1, 1> Gems;
    UpdateField<UF::CraftingOrderData, -1, 2> Data;
    OptionalUpdateField<WorldPackets::Item::ItemInstance, -1, 3> RecraftItemInfo;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct PersonalCraftingOrderCount : public IsUpdateFieldStructureTag, public HasChangesMask<2>
{
    UpdateField<int32, -1, 0> ProfessionID;
    UpdateField<uint32, -1, 1> Count;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct CategoryCooldownMod : public IsUpdateFieldStructureTag
{
    int32 SpellCategoryID;
    int32 ModCooldown;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    bool operator==(CategoryCooldownMod const& right) const;
    bool operator!=(CategoryCooldownMod const& right) const { return !(*this == right); }
};

struct WeeklySpellUse : public IsUpdateFieldStructureTag
{
    int32 SpellCategoryID;
    uint8 Uses;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    bool operator==(WeeklySpellUse const& right) const;
    bool operator!=(WeeklySpellUse const& right) const { return !(*this == right); }
};

struct StablePetInfo : public IsUpdateFieldStructureTag, public HasChangesMask<8>
{
    UpdateField<uint32, 0, 1> PetSlot;
    UpdateField<uint32, 0, 2> PetNumber;
    UpdateField<uint32, 0, 3> CreatureID;
    UpdateField<uint32, 0, 4> DisplayID;
    UpdateField<uint32, 0, 5> ExperienceLevel;
    UpdateField<std::string, 0, 6> Name;
    UpdateField<uint8, 0, 7> PetFlags;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct StableInfo : public IsUpdateFieldStructureTag, public HasChangesMask<3>
{
    DynamicUpdateField<UF::StablePetInfo, 0, 1> Pets;
    UpdateField<ObjectGuid, 0, 2> StableMaster;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct CollectableSourceTrackedData : public IsUpdateFieldStructureTag, public HasChangesMask<4>
{
    UpdateField<int32, 0, 1> TargetType;
    UpdateField<int32, 0, 2> TargetID;
    UpdateField<int32, 0, 3> CollectableSourceInfoID;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct Research : public IsUpdateFieldStructureTag
{
    int16 ResearchProjectID;

    void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
    bool operator==(Research const& right) const;
    bool operator!=(Research const& right) const { return !(*this == right); }
};

struct ActivePlayerData : public IsUpdateFieldStructureTag, public HasChangesMask<1454>
{
    UpdateField<bool, 0, 1> BackpackAutoSortDisabled;
    UpdateField<bool, 0, 2> BackpackSellJunkDisabled;
    UpdateField<bool, 0, 3> BankAutoSortDisabled;
    UpdateField<bool, 0, 4> SortBagsRightToLeft;
    UpdateField<bool, 0, 5> InsertItemsLeftToRight;
    UpdateField<bool, 0, 6> HasPerksProgramPendingReward;
    UpdateFieldArray<DynamicUpdateFieldBase<uint64>, 9, 36, 37> DataFlags;
    UpdateFieldArray<DynamicUpdateFieldBase<uint16>, 1, 38, 39> ResearchSites;
    UpdateFieldArray<DynamicUpdateFieldBase<uint32>, 1, 40, 41> ResearchSiteProgress;
    UpdateFieldArray<DynamicUpdateFieldBase<UF::Research>, 1, 42, 43> Research;
    DynamicUpdateField<uint64, 0, 7> KnownTitles;
    DynamicUpdateField<int32, 0, 9> DailyQuestsCompleted;
    DynamicUpdateField<int32, 0, 10> AvailableQuestLineXQuestIDs;
    DynamicUpdateField<int32, 0, 11> Heirlooms;
    DynamicUpdateField<uint32, 0, 12> HeirloomFlags;
    DynamicUpdateField<int32, 0, 13> Toys;
    DynamicUpdateField<uint32, 0, 14> ToyFlags;
    DynamicUpdateField<uint32, 0, 15> Transmog;
    DynamicUpdateField<int32, 0, 16> ConditionalTransmog;
    DynamicUpdateField<int32, 0, 17> SelfResSpells;
    DynamicUpdateField<uint32, 0, 18> RuneforgePowers;
    DynamicUpdateField<uint32, 0, 19> TransmogIllusions;
    DynamicUpdateField<UF::SpellPctModByLabel, 0, 21> SpellPctModByLabel;
    DynamicUpdateField<UF::SpellFlatModByLabel, 0, 22> SpellFlatModByLabel;
    DynamicUpdateField<UF::MawPower, 0, 23> MawPowers;
    DynamicUpdateField<UF::MultiFloorExplore, 0, 24> MultiFloorExploration;
    DynamicUpdateField<UF::RecipeProgressionInfo, 0, 25> RecipeProgression;
    DynamicUpdateField<UF::ReplayedQuest, 0, 26> ReplayedQuests;
    DynamicUpdateField<UF::QuestLog, 0, 27> TaskQuests;
    DynamicUpdateField<int32, 0, 28> DisabledSpells;
    DynamicUpdateField<UF::PersonalCraftingOrderCount, 0, 31> PersonalCraftingOrderCounts;
    DynamicUpdateField<UF::CategoryCooldownMod, 32, 33> CategoryCooldownMods;
    DynamicUpdateField<UF::WeeklySpellUse, 32, 34> WeeklySpellUses;
    DynamicUpdateField<UF::CollectableSourceTrackedData, 32, 35> TrackedCollectableSources;
    DynamicUpdateField<UF::PVPInfo, 0, 8> PvpInfo;
    DynamicUpdateField<UF::CharacterRestriction, 0, 20> CharacterRestrictions;
    DynamicUpdateField<UF::TraitConfig, 0, 29> TraitConfigs;
    DynamicUpdateField<UF::CraftingOrder, 0, 30> CraftingOrders;
    UpdateField<ObjectGuid, 32, 44> FarsightObject;
    UpdateField<ObjectGuid, 32, 45> SummonedBattlePetGUID;
    UpdateField<uint64, 32, 46> Coinage;
    UpdateField<int32, 32, 47> XP;
    UpdateField<int32, 32, 48> NextLevelXP;
    UpdateField<int32, 32, 49> TrialXP;
    UpdateField<UF::SkillInfo, 32, 50> Skill;
    UpdateField<int32, 32, 51> CharacterPoints;
    UpdateField<int32, 32, 52> MaxTalentTiers;
    UpdateField<uint32, 32, 53> TrackCreatureMask;
    UpdateField<float, 32, 54> MainhandExpertise;
    UpdateField<float, 32, 55> OffhandExpertise;
    UpdateField<float, 32, 56> RangedExpertise;
    UpdateField<float, 32, 57> CombatRatingExpertise;
    UpdateField<float, 32, 58> BlockPercentage;
    UpdateField<float, 32, 59> DodgePercentage;
    UpdateField<float, 32, 60> DodgePercentageFromAttribute;
    UpdateField<float, 32, 61> ParryPercentage;
    UpdateField<float, 32, 62> ParryPercentageFromAttribute;
    UpdateField<float, 32, 63> CritPercentage;
    UpdateField<float, 32, 64> RangedCritPercentage;
    UpdateField<float, 32, 65> OffhandCritPercentage;
    UpdateField<float, 32, 66> SpellCritPercentage;
    UpdateField<int32, 32, 67> ShieldBlock;
    UpdateField<float, 32, 68> ShieldBlockCritPercentage;
    UpdateField<float, 32, 69> Mastery;
    UpdateField<float, 32, 70> Speed;
    UpdateField<float, 32, 71> Avoidance;
    UpdateField<float, 72, 73> Sturdiness;
    UpdateField<int32, 72, 74> Versatility;
    UpdateField<float, 72, 75> VersatilityBonus;
    UpdateField<float, 72, 76> PvpPowerDamage;
    UpdateField<float, 72, 77> PvpPowerHealing;
    UpdateField<int32, 72, 78> ModHealingDonePos;
    UpdateField<float, 72, 79> ModHealingPercent;
    UpdateField<float, 72, 80> ModPeriodicHealingDonePercent;
    UpdateField<float, 72, 81> ModSpellPowerPercent;
    UpdateField<float, 72, 82> ModResiliencePercent;
    UpdateField<float, 72, 83> OverrideSpellPowerByAPPercent;
    UpdateField<float, 72, 84> OverrideAPBySpellPowerPercent;
    UpdateField<int32, 72, 85> ModTargetResistance;
    UpdateField<int32, 72, 86> ModTargetPhysicalResistance;
    UpdateField<uint32, 72, 87> LocalFlags;
    UpdateField<uint8, 72, 88> GrantableLevels;
    UpdateField<uint8, 72, 89> MultiActionBars;
    UpdateField<uint8, 72, 90> LifetimeMaxRank;
    UpdateField<uint8, 72, 91> NumRespecs;
    UpdateField<uint32, 72, 92> PvpMedals;
    UpdateField<uint16, 72, 93> TodayHonorableKills;
    UpdateField<uint16, 72, 94> YesterdayHonorableKills;
    UpdateField<uint32, 72, 95> LifetimeHonorableKills;
    UpdateField<int32, 72, 96> WatchedFactionIndex;
    UpdateField<int32, 72, 97> MaxLevel;
    UpdateField<int32, 72, 98> ScalingPlayerLevelDelta;
    UpdateField<int32, 72, 99> MaxCreatureScalingLevel;
    UpdateField<int32, 72, 100> PetSpellPower;
    UpdateField<float, 72, 101> UiHitModifier;
    UpdateField<float, 72, 102> UiSpellHitModifier;
    UpdateField<int32, 72, 103> HomeRealmTimeOffset;
    UpdateField<float, 104, 105> ModPetHaste;
    UpdateField<int8, 104, 106> JailersTowerLevelMax;
    UpdateField<int8, 104, 107> JailersTowerLevel;
    UpdateField<uint8, 104, 108> LocalRegenFlags;
    UpdateField<uint8, 104, 109> AuraVision;
    UpdateField<uint8, 104, 110> NumBackpackSlots;
    UpdateField<int32, 104, 111> OverrideSpellsID;
    UpdateField<uint16, 104, 112> LootSpecID;
    UpdateField<uint32, 104, 113> OverrideZonePVPType;
    UpdateField<int32, 104, 114> Honor;
    UpdateField<int32, 104, 115> HonorNextLevel;
    UpdateField<int32, 104, 116> PerksProgramCurrency;
    UpdateField<uint8, 104, 117> NumBankSlots;
    UpdateField<UF::ResearchHistory, 104, 118> ResearchHistory;
    UpdateField<WorldPackets::PerksProgram::PerksVendorItem, 104, 119> FrozenPerksVendorItem;
    UpdateField<UF::ActivePlayerUnk901, 104, 121> Field_1410;
    OptionalUpdateField<UF::QuestSession, 104, 120> QuestSession;
    UpdateField<int32, 104, 122> UiChromieTimeExpansionID;
    UpdateField<int32, 104, 123> TimerunningSeasonID;
    UpdateField<int32, 104, 124> TransportServerTime;
    UpdateField<uint32, 104, 125> WeeklyRewardsPeriodSinceOrigin;               // week count since Cfg_RegionsEntry::ChallengeOrigin
    UpdateField<int16, 104, 126> DEBUGSoulbindConduitRank;
    UpdateField<WorldPackets::MythicPlus::DungeonScoreData, 104, 127> DungeonScore;
    UpdateField<uint32, 104, 128> ActiveCombatTraitConfigID;
    UpdateField<int32, 104, 129> ItemUpgradeHighOnehandWeaponItemID;
    UpdateField<int32, 104, 130> ItemUpgradeHighFingerItemID;
    UpdateField<float, 104, 131> ItemUpgradeHighFingerWatermark;
    UpdateField<int32, 104, 132> ItemUpgradeHighTrinketItemID;
    UpdateField<float, 104, 133> ItemUpgradeHighTrinketWatermark;
    UpdateField<uint64, 104, 134> LootHistoryInstanceID;
    OptionalUpdateField<UF::StableInfo, 104, 135> PetStable;
    UpdateField<uint8, 136, 137> RequiredMountCapabilityFlags;
    UpdateFieldArray<ObjectGuid, 227, 138, 139> InvSlots;
    UpdateFieldArray<UF::RestInfo, 2, 366, 367> RestInfo;
    UpdateFieldArray<int32, 7, 369, 370> ModDamageDonePos;
    UpdateFieldArray<int32, 7, 369, 377> ModDamageDoneNeg;
    UpdateFieldArray<float, 7, 369, 384> ModDamageDonePercent;
    UpdateFieldArray<float, 7, 369, 391> ModHealingDonePercent;
    UpdateFieldArray<float, 3, 398, 399> WeaponDmgMultipliers;
    UpdateFieldArray<float, 3, 398, 402> WeaponAtkSpeedMultipliers;
    UpdateFieldArray<uint32, 12, 405, 406> BuybackPrice;
    UpdateFieldArray<int64, 12, 405, 418> BuybackTimestamp;
    UpdateFieldArray<int32, 32, 430, 431> CombatRatings;
    UpdateFieldArray<uint32, 4, 463, 464> NoReagentCostMask;
    UpdateFieldArray<int32, 2, 468, 469> ProfessionSkillLine;
    UpdateFieldArray<uint32, 5, 471, 472> BagSlotFlags;
    UpdateFieldArray<uint32, 7, 477, 478> BankBagSlotFlags;
    UpdateFieldArray<uint64, 950, 485, 486> QuestCompleted;
    UpdateFieldArray<float, 17, 1436, 1437> ItemUpgradeHighWatermark;

    void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Player const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct GameObjectData : public IsUpdateFieldStructureTag, public HasChangesMask<25>
{
    UpdateField<std::vector<uint32>, 0, 1> StateWorldEffectIDs;
    struct StateWorldEffectIDsTag : ViewerDependentValueTag<std::vector<uint32>> {};
    DynamicUpdateField<int32, 0, 2> EnableDoodadSets;
    DynamicUpdateField<int32, 0, 3> WorldEffects;
    UpdateField<int32, 0, 4> DisplayID;
    UpdateField<uint32, 0, 5> SpellVisualID;
    UpdateField<uint32, 0, 6> StateSpellVisualID;
    struct StateSpellVisualIDTag : ViewerDependentValueTag<uint32> {};
    UpdateField<uint32, 0, 7> SpawnTrackingStateAnimID;
    struct StateAnimIDTag : ViewerDependentValueTag<uint32> {};
    UpdateField<uint32, 0, 8> SpawnTrackingStateAnimKitID;
    struct StateAnimKitIDTag : ViewerDependentValueTag<uint32> {};
    UpdateField<uint32, 0, 9> StateWorldEffectsQuestObjectiveID;
    UpdateField<ObjectGuid, 0, 10> CreatedBy;
    UpdateField<ObjectGuid, 0, 11> GuildGUID;
    UpdateField<uint32, 0, 12> Flags;
    struct FlagsTag : ViewerDependentValueTag<uint32> {};
    UpdateField<QuaternionData, 0, 13> ParentRotation;
    UpdateField<int32, 0, 14> FactionTemplate;
    UpdateField<int8, 0, 15> State;
    struct StateTag : ViewerDependentValueTag<int8> {};
    UpdateField<int8, 0, 16> TypeID;
    UpdateField<uint8, 0, 17> PercentHealth;
    UpdateField<uint32, 0, 18> ArtKit;
    UpdateField<uint32, 0, 19> CustomParam;
    UpdateField<int32, 0, 20> Level;
    UpdateField<uint32, 0, 21> AnimGroupInstance;
    UpdateField<uint32, 0, 22> UiWidgetItemID;
    UpdateField<uint32, 0, 23> UiWidgetItemQuality;
    UpdateField<uint32, 0, 24> UiWidgetItemUnknown1000;

    void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, GameObject const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, GameObject const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, GameObject const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct DynamicObjectData : public IsUpdateFieldStructureTag, public HasChangesMask<7>
{
    UpdateField<ObjectGuid, 0, 1> Caster;
    UpdateField<uint8, 0, 2> Type;
    UpdateField<UF::SpellCastVisual, 0, 3> SpellVisual;
    UpdateField<int32, 0, 4> SpellID;
    UpdateField<float, 0, 5> Radius;
    UpdateField<uint32, 0, 6> CastTime;

    void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, DynamicObject const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, DynamicObject const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, DynamicObject const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct CorpseData : public IsUpdateFieldStructureTag, public HasChangesMask<33>
{
    DynamicUpdateField<UF::ChrCustomizationChoice, 0, 1> Customizations;
    UpdateField<uint32, 0, 2> DynamicFlags;
    UpdateField<ObjectGuid, 0, 3> Owner;
    UpdateField<ObjectGuid, 0, 4> PartyGUID;
    UpdateField<ObjectGuid, 0, 5> GuildGUID;
    UpdateField<uint32, 0, 6> DisplayID;
    UpdateField<uint8, 0, 7> RaceID;
    UpdateField<uint8, 0, 8> Sex;
    UpdateField<uint8, 0, 9> Class;
    UpdateField<uint32, 0, 10> Flags;
    UpdateField<int32, 0, 11> FactionTemplate;
    UpdateField<uint32, 0, 12> StateSpellVisualKitID;
    UpdateFieldArray<uint32, 19, 13, 14> Items;

    void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Corpse const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Corpse const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Corpse const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct ScaleCurve : public IsUpdateFieldStructureTag, public HasChangesMask<7>
{
    UpdateField<bool, 0, 1> OverrideActive;
    UpdateField<uint32, 0, 2> StartTimeOffset;
    UpdateField<uint32, 0, 3> ParameterCurve;
    UpdateFieldArray<TaggedPosition<Position::XY>, 2, 4, 5> Points;

    void WriteCreate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AreaTrigger const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct VisualAnim : public IsUpdateFieldStructureTag, public HasChangesMask<5>
{
    UpdateField<bool, 0, 1> Field_C;
    UpdateField<uint32, 0, 2> AnimationDataID;
    UpdateField<uint32, 0, 3> AnimKitID;
    UpdateField<uint32, 0, 4> AnimProgress;

    void WriteCreate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AreaTrigger const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct AreaTriggerData : public IsUpdateFieldStructureTag, public HasChangesMask<26>
{
    UpdateField<bool, 0, 1> HeightIgnoresScale;
    UpdateField<bool, 0, 2> Field_261;
    UpdateField<UF::ScaleCurve, 0, 3> OverrideScaleCurve;
    UpdateField<UF::ScaleCurve, 0, 4> ExtraScaleCurve;
    UpdateField<UF::ScaleCurve, 0, 5> OverrideMoveCurveX;
    UpdateField<UF::ScaleCurve, 0, 6> OverrideMoveCurveY;
    UpdateField<UF::ScaleCurve, 0, 7> OverrideMoveCurveZ;
    UpdateField<ObjectGuid, 0, 8> Caster;
    UpdateField<uint32, 0, 9> Duration;
    UpdateField<uint32, 0, 10> TimeToTarget;
    UpdateField<uint32, 0, 11> TimeToTargetScale;
    UpdateField<uint32, 0, 12> TimeToTargetExtraScale;
    UpdateField<uint32, 0, 13> TimeToTargetPos;                                 // Linked to m_overrideMoveCurve
    UpdateField<int32, 0, 14> SpellID;
    UpdateField<int32, 0, 15> SpellForVisuals;
    UpdateField<UF::SpellCastVisual, 0, 16> SpellVisual;
    UpdateField<float, 0, 17> BoundsRadius2D;
    UpdateField<uint32, 0, 18> DecalPropertiesID;
    UpdateField<ObjectGuid, 0, 19> CreatingEffectGUID;
    UpdateField<uint32, 0, 20> NumUnitsInside;
    UpdateField<uint32, 0, 21> NumPlayersInside;                                // When not 0 this causes SpellVisualEvent 14 to trigger, playing alternate visuals, typically used by "SOAK THIS" areatriggers
    UpdateField<ObjectGuid, 0, 22> OrbitPathTarget;
    UpdateField<TaggedPosition<Position::XYZ>, 0, 23> RollPitchYaw;
    UpdateField<int32, 0, 24> PositionalSoundKitID;
    UpdateField<UF::VisualAnim, 0, 25> VisualAnim;

    void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, AreaTrigger const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, AreaTrigger const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, AreaTrigger const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct SceneObjectData : public IsUpdateFieldStructureTag, public HasChangesMask<5>
{
    UpdateField<int32, 0, 1> ScriptPackageID;
    UpdateField<uint32, 0, 2> RndSeedVal;
    UpdateField<ObjectGuid, 0, 3> CreatedBy;
    UpdateField<uint32, 0, 4> SceneType;

    void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Object const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

struct ConversationLine : public IsUpdateFieldStructureTag
{
    int32 ConversationLineID;
    int32 BroadcastTextID;
    uint32 StartTime;
    struct StartTimeTag : ViewerDependentValueTag<uint32> {};
    int32 UiCameraID;
    uint8 ActorIndex;
    uint8 Flags;
    uint8 ChatType;

    void WriteCreate(ByteBuffer& data, Conversation const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Conversation const* owner, Player const* receiver) const;
    bool operator==(ConversationLine const& right) const;
    bool operator!=(ConversationLine const& right) const { return !(*this == right); }
};

struct ConversationActor : public IsUpdateFieldStructureTag
{
    uint32 CreatureID;
    uint32 CreatureDisplayInfoID;
    ObjectGuid ActorGUID;
    int32 Id;
    uint32 Type;
    uint32 NoActorObject;

    void WriteCreate(ByteBuffer& data, Conversation const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Conversation const* owner, Player const* receiver) const;
    bool operator==(ConversationActor const& right) const;
    bool operator!=(ConversationActor const& right) const { return !(*this == right); }
};

struct ConversationData : public IsUpdateFieldStructureTag, public HasChangesMask<7>
{
    UpdateField<bool, 0, 1> DontPlayBroadcastTextSounds;
    UpdateField<std::vector<UF::ConversationLine>, 0, 2> Lines;
    DynamicUpdateField<UF::ConversationActor, 0, 3> Actors;
    UpdateField<int32, 0, 4> LastLineEndTime;
    struct LastLineEndTimeTag : ViewerDependentValueTag<int32> {};
    UpdateField<uint32, 0, 5> Progress;
    UpdateField<uint32, 0, 6> Flags;

    void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Conversation const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Conversation const* owner, Player const* receiver) const;
    void WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Conversation const* owner, Player const* receiver) const;
    void ClearChangesMask();
};

}

#endif // UpdateFields_h__
